从基本层面来看,一个 链表 是一个递归数据结构,其定义基于自身的存在或组成。列表要么是 空的 (表示为 []),要么由一个 头节点 包含单个值,以及一个 尾部 本身也是一个完整的列表。
1. 递归定义
通过将尾部定义为“自身是一个列表”,我们允许无限嵌套。这可以通过构建 [ 1 | [ 2 | [ 3 | [ ] ] ] ]来说明,其中每个管道操作符(|)将当前值与剩余结构分隔开。
2. 原始结构与抽象层
Erlang 虚拟机(BEAM)中的原始列表是简单的数据结构。诸如 List.flatten/1 等行为是 抽象 由 Elixir 的 List 模块提供的。原始数据结构并不“知道”如何自行展开;该模块提供了遍历嵌套头尾的逻辑。
3. “套娃”类比
可以把链表想象成一套俄罗斯套娃。最外层的娃娃就是 头节点。当你打开它时,会发现恰好一样东西:另一个娃娃(即 尾部)。只有当打开最后一个最小的娃娃时,才发现里面什么都没有,这才达到 空 状态。
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>